package com.library.uiframework.widget.state;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.library.uiframework.R;

/**
 * @author hongkai.qian
 * @version 1.0.0
 * @since 15-11-30
 * 自定义加载View.
 * 包含四种状态, 成功,失败,正在加载,成功但没有数据, only wifi, no copyright.
 * 使用时需指定成功,失败,没数据的Layout
 */
public class StateView extends FrameLayout {
    private OnConfigStateViewListener mOnConfigStateViewListener;

    private State mCurrentState = State.SUCCESS;

    private static class StateProperty {
        private View mView;
        private int mLayoutId;
        private List<View> mViews;
        private OnCreateStateViewListener mCreateStateViewListener;
    }

    private SparseArray<StateProperty> mStateProperties = new SparseArray<>();

    /**
     *
     */
    public enum State {
        /**
         * 正在加载
         */
        LOADING,

        /**
         * 加载成功
         */
        SUCCESS,

        /**
         * 没有网络
         */
        NO_NETWORK,

        /**
         * 加载失败
         */
        FAILED,

        /**
         * 没有数据
         */
        NO_DATA,

        /**
         * 只wifi
         */
        ONLY_WIFI,

        /**
         * 没有版权,服务不可用
         */
        NO_COPYRIGHT,
    }

    /**
     * 使用{@link StateView#setOnConfigStateViewListener(OnConfigStateViewListener)}
     */
    public interface OnRetryRequestListener {
        /**
         * 此接口仅为老代码保留,新代码请勿使用
         */
        void onRetryRequested();
    }

    public interface OnConfigStateViewListener {
        /**
         * @param view  要配置的view
         * @param state 当前状态
         */
        void onConfigStateView(View view, State state);
    }

    /**
     * @param context 上下文对象
     */
    public StateView(Context context) {
        this(context, null);
    }

    /**
     * 构造器
     *
     * @param context 上下文对象
     * @param attrs   属性值集合
     */
    public StateView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    /**
     * 构造器
     *
     * @param context  上下文对象
     * @param attrs    属性值集合
     * @param defStyle 风格
     */
    public StateView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.StateView);
        int failedId = typedArray.getResourceId(R.styleable.StateView_failed_view, R.layout.uiframework_loadingview_failed);
        int successId = typedArray.getResourceId(R.styleable.StateView_success_view, -1);
        int loadingId = typedArray.getResourceId(R.styleable.StateView_loading_view, R.layout.uiframework_loadingview_loading);
        int nodataId = typedArray.getResourceId(R.styleable.StateView_nodata_view, R.layout.uiframework_loadingview_nodata);
        int onlyWifiId = typedArray.getResourceId(R.styleable.StateView_only_wifi_view, -1);
        int noCopyrightId = typedArray.getResourceId(R.styleable.StateView_no_copyright_view, -1);
        int noNetworkId = typedArray.getResourceId(R.styleable.StateView_no_network_view, R.layout.uiframework_loadingview_no_network);

        setStateProperty(State.FAILED, failedId);
        setStateProperty(State.SUCCESS, successId);
        setStateProperty(State.LOADING, loadingId);
        setStateProperty(State.NO_DATA, nodataId);
        setStateProperty(State.ONLY_WIFI, onlyWifiId);
        setStateProperty(State.NO_COPYRIGHT, noCopyrightId);
        setStateProperty(State.NO_NETWORK, noNetworkId);

        typedArray.recycle();
        setState(State.SUCCESS);
        setBackgroundResource(R.color.global_state_bg);
    }

    private LayoutInflater buildInflater(Context context) {
//        if (context instanceof LayoutInflaterProvider) {
//            return ((LayoutInflaterProvider) context).requestLayoutInflater();
//        }
        return LayoutInflater.from(context);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        View contentView = getChildAt(0);
        if (contentView != null) {
            setStateProperty(State.SUCCESS, contentView);
        }
    }

    public void setStateProperty(State state, int layoutId) {
        StateProperty stateProperty = mStateProperties.get(state.ordinal());
        if (stateProperty == null) {
            stateProperty = new StateProperty();
        }
        stateProperty.mLayoutId = layoutId;
        mStateProperties.put(state.ordinal(), stateProperty);
    }

    public void setStateProperty(State state, View view) {
        StateProperty stateProperty = mStateProperties.get(state.ordinal());
        if (stateProperty == null) {
            stateProperty = new StateProperty();
            mStateProperties.put(state.ordinal(), stateProperty);
        }
        stateProperty.mView = view;
        if (view.getParent() == null) {
            addView(view);
        }
        view.setVisibility(mCurrentState == state ? View.VISIBLE : View.GONE);
    }

    /**
     * for weex state view支持多节点
     *
     * @param state state
     * @param view  view
     */
    public void addStateProperty(State state, View view) {
        StateProperty stateProperty = mStateProperties.get(state.ordinal());
        if (stateProperty == null) {
            stateProperty = new StateProperty();
            mStateProperties.put(state.ordinal(), stateProperty);
        }
        if (stateProperty.mViews == null) {
            stateProperty.mViews = new ArrayList<>();
        }
        if (!stateProperty.mViews.contains(view)) {
            stateProperty.mViews.add(view);
        }
        if (view.getParent() == null) {
            addView(view);
        }
        view.setVisibility(mCurrentState == state ? View.VISIBLE : View.GONE);
    }

    public void setStateProperty(State state, OnCreateStateViewListener listener) {
        StateProperty stateProperty = mStateProperties.get(state.ordinal());
        if (stateProperty == null) {
            stateProperty = new StateProperty();
        }
        stateProperty.mCreateStateViewListener = listener;
        mStateProperties.put(state.ordinal(), stateProperty);
    }

    public View getStateView(State state) {
        StateProperty stateProperty = mStateProperties.get(state.ordinal());
        if (stateProperty == null) {
            return null;
        }
        return stateProperty.mView;
    }

    /**
     * 设置View的状态, 对于loading状态下自动显示动画
     *
     * @param state State
     */
    public void setState(State state) {
        setState(state, true);
    }

    /**
     * 设置View的状态
     *
     * @param state     State
     * @param animation 对于loading状态是否显示动画, false的目的是刚进页面时不显示动画, 直到onLoadFinished后可显示动画
     */
    public void setState(State state, boolean animation) {
        mCurrentState = state;
        final int size = mStateProperties.size();
        for (int index = 0; index < size; index++) {
            final StateProperty stateProperty = mStateProperties.valueAt(index);
            final int key = mStateProperties.keyAt(index);
            if (stateProperty == null) {
                continue;
            }
            if (key == state.ordinal()) {
                View view = stateProperty.mView;
                if (stateProperty.mViews != null && !stateProperty.mViews.isEmpty()) {
                    for (View v : stateProperty.mViews) {
                        v.setVisibility(View.VISIBLE);
                    }
                } else if (view == null) {
                    final OnCreateStateViewListener createStateViewListener = stateProperty.mCreateStateViewListener;
                    final int layoutId = stateProperty.mLayoutId;
                    if (createStateViewListener != null) {
                        view = createStateViewListener.onCreateStateView(this, state);
                    } else if (stateProperty.mLayoutId > 0) {
                        view = buildInflater(getContext()).inflate(layoutId, this, false);
                        if (mOnConfigStateViewListener != null) {
                            mOnConfigStateViewListener.onConfigStateView(view, state);
                        }
                    }
                    if (view != null) {
                        addView(view);
                    }
                    stateProperty.mView = view;
                } else {
                    if (stateProperty.mLayoutId <= 0 && stateProperty.mCreateStateViewListener == null && indexOfChild(view) < 0) {
                        addView(view);
                    }
                    view.setVisibility(View.VISIBLE);
                }
                showAnimation(view, animation, key);
            } else if (stateProperty.mView != null) {
                View view = stateProperty.mView;
                view.setVisibility(View.GONE);
                showAnimation(view, false, key);
            } else if (stateProperty.mViews != null && !stateProperty.mViews.isEmpty()) {
                for (View view : stateProperty.mViews) {
                    view.setVisibility(View.GONE);
                }
            }
        }
    }

    public State getCurrentState() {
        return mCurrentState;
    }

    private void showAnimation(View view, boolean show, int state) {
        if (state == State.LOADING.ordinal() && view != null) {
            View lview = view.findViewById(R.id.loading_view);
            if (lview instanceof Loading) {
                Loading loadingView = (Loading) lview;
                if (show) {
                    loadingView.startAnimation();
                } else {
                    loadingView.stopAnimation();
                }
            }
        }
    }

    /**
     * 显示当前状态的动画,如果有的话
     */
    public void showAnimation() {
        final View stateView = getStateView(mCurrentState);
        showAnimation(stateView, true, mCurrentState.ordinal());
    }

    /**
     * stop animation
     */
    public void stopAnimation() {
        final View stateView = getStateView(mCurrentState);
        if (mCurrentState == State.LOADING && stateView != null) {
            View lview = stateView.findViewById(R.id.loading_view);
            if (lview instanceof Loading) {
                Loading loadingView = (Loading) lview;
                loadingView.stopAnimation();
            }
        }
    }

    public interface OnCreateStateViewListener {
        /**
         * @param parent parent View
         * @param state  state
         * @return view
         */
        View onCreateStateView(ViewGroup parent, State state);
    }

    /**
     * @param onConfigStateViewListener 当布局中的view要显示时回调,给一次配置内容的机会,如文字内容
     */
    public void setOnConfigStateViewListener(OnConfigStateViewListener onConfigStateViewListener) {
        mOnConfigStateViewListener = onConfigStateViewListener;
    }

}
